import time,os
import json
import hmac
import django
import hashlib
import base64
import random

import requests
from datetime import datetime, timedelta
from typing import Dict, List, Optional
from sqlalchemy.orm import sessionmaker
import traceback
from sqlalchemy import and_, create_engine, or_
from sqlalchemy import text
from sqlalchemy import null
from django.http import JsonResponse
from django.views import View
import time
from sqlalchemy import desc  # 导入 desc 方法
from app.intereface_amazon.databasemodel import Amazon_asinupload_xue_todb, AmazonProduct, Message2
DATABASE_URL = "mysql+pymysql://root:Zb_200407@gz-cdb-d4j7h16x.sql.tencentcdb.com:22333/walmart"
import threading
# 创建全局锁
download_lock = threading.Lock()
downmessage_lock=threading.Lock()
is_downloading = False
from sqlalchemy import func, null
import os
import django

# 设置 Django 环境
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'walmartca.settings')  # 替换为您的项目名称
is_downingmessage=False
class SPAPI(View):
    """亚马逊SP API客户端（纯HTTP实现，无需AWS SDK）"""
    def get(self, request, *args, **kwargs):
        print("开始下载亚马逊数据...")
        time.sleep(5)  # 模拟下载过程
        print("数据下载成功！")
        return JsonResponse({'status': 'success', 'message': '数据下载成功！'})
    def __init__(self, credentials: Dict, region: str = "NA"):
        """
        初始化SP API客户端
        
        Args:
            credentials: 包含认证信息的字典
            region: 区域代码（NA: 北美, EU: 欧洲, JP: 日本）
        """
        self.credentials = credentials
        self.access_token = None
        self.region = region
        self.endpoints = {
            "NA": "https://sellingpartnerapi-na.amazon.com",
            "EU": "https://sellingpartnerapi-eu.amazon.com",
            "JP": "https://sellingpartnerapi-jp.amazon.com"
        }
        self.refresh_access_token()
        self.SELLER_ID = "A26FR646PJC2K3"
        self.region = "NA"

        self.engine = create_engine(DATABASE_URL)
        Session = sessionmaker(bind=self.engine)
        self.session = Session()
    
    def refresh_access_token(self) -> None:
        """刷新LWA访问令牌"""
        url = "https://api.amazon.com/auth/o2/token"
        data = {
            "grant_type": "refresh_token",
            "refresh_token": self.credentials["refresh_token"],
            "client_id": self.credentials["lwa_client_id"],
            "client_secret": self.credentials["lwa_client_secret"]
        }
        
        response = requests.post(url, data=data)
        response.raise_for_status()
        token_data = response.json()
        self.access_token = token_data["access_token"]
    
    def _get_headers(self) -> Dict:
        """获取API请求头"""
        self.refresh_access_token()
        return {
            "Authorization": f"Bearer {self.access_token}",
            "Content-Type": "application/json",
            "x-amz-access-token": self.access_token
        }
    
    # ===== 产品数据下载（Reports API） =====
    def create_product_report(self, report_type: str, marketplace_ids: List[str]) -> Dict:
        """创建产品报告请求"""
        url = f"{self.endpoints[self.region]}/reports/2021-06-30/reports"
        headers = self._get_headers()
        body = {
            "reportType": report_type,
            "marketplaceIds": marketplace_ids
        }
        
        response = requests.post(url, headers=headers, json=body)
        response.raise_for_status()
        return response.json()
    
    def get_report_status(self, report_id: str) -> Dict:
        """获取报告状态"""
        url = f"{self.endpoints[self.region]}/reports/2021-06-30/reports/{report_id}"
        headers = self._get_headers()
        
        response = requests.get(url, headers=headers)
        response.raise_for_status()
        return response.json()
    
    def get_report_document(self, document_id: str) -> Dict:
        """获取报告下载URL"""
        url = f"{self.endpoints[self.region]}/reports/2021-06-30/documents/{document_id}"
        headers = self._get_headers()
        
        response = requests.get(url, headers=headers)
        response.raise_for_status()
        return response.json()
    
    def download_report(self, download_url: str) -> str:
        """下载报告内容"""
        response = requests.get(download_url)
        response.raise_for_status()
        return response.text
    
    def get_report_data(self, report_id: str) -> str:
        """获取报告数据内容"""
        max_attempts = 20
        for attempt in range(max_attempts):
            time.sleep(30)  # 等待10秒
            report_status = self.get_report_status(report_id)
            
            if report_status["processingStatus"] == "DONE":
                document_id = report_status["reportDocumentId"]
                document_info = self.get_report_document(document_id)
                download_url = document_info["url"]
                return self.download_report(download_url)
            
            print(f"尝试 {attempt+1}/{max_attempts}: 报告状态 - {report_status['processingStatus']}")
        
        raise Exception("报告生成超时")
    
    # ===== 产品数据上传（Feeds API） =====
    def create_feed_document(self, content_type: str = "text/tab-separated-values; charset=UTF-8") -> Dict:
        """创建Feed文档并获取上传URL"""
        url = f"{self.endpoints[self.region]}/feeds/2020-09-04/documents"
        # url=f"https://sellingpartnerapi-na.amazon.com/feeds/2021-06-30/documents"
        headers = {
            "Authorization": f"Bearer {self.access_token}",
            "Content-Type": "application/json" 
            }
        body = {"contentType": content_type}
        
        response = requests.post(url, headers=headers, json=body)
        response.raise_for_status()

 

        return response.json()
    
    def upload_feed_data(self, upload_url: str, feed_content: str) -> None:
        """上传Feed数据到指定URL"""
        headers = {"Content-Type": "text/tab-separated-values; charset=UTF-8"}
        response = requests.put(upload_url, headers=headers, data=feed_content)
        response.raise_for_status()
    
    def submit_feed(self, feed_type: str, document_id: str, marketplace_ids: List[str]) -> Dict:
        """提交Feed处理请求"""
        url = f"{self.endpoints[self.region]}/feeds/2020-09-04/feeds"
        headers = self._get_headers()
        body = {
            "feedType": feed_type,
            "inputFeedDocumentId": document_id,
            "marketplaceIds": marketplace_ids
        }
        
        response = requests.post(url, headers=headers, json=body)
        response.raise_for_status()
        return response.json()
    
    def get_feed_status(self, feed_id: str) -> Dict:
        """获取Feed处理状态"""
        url = f"{self.endpoints[self.region]}/feeds/2020-09-04/feeds/{feed_id}"
        headers = self._get_headers()
        
        response = requests.get(url, headers=headers)
        response.raise_for_status()
        return response.json()
    



    def save_products_to_db(self, products_data):
        """
        将产品数据保存到数据库，如果存在则更新
        
        参数:
            products_data: 产品数据列表，每个元素是一个字典
        """
        def convert_keys_to_snake_case(data):
            """将字典中的连字符键转换为下划线形式"""
            snake_case_data = {}
            for key, value in data.items():
                # 将连字符替换为下划线
                snake_key = key.replace('-', '_')
                snake_case_data[snake_key] = value
            return snake_case_data
        
        session = self.session
        try:
            for product_data in products_data:
                try:
                    # 检查产品是否已存在（使用asin作为唯一标识）
                    existing_product = session.query(AmazonProduct).filter_by(asin=product_data['asin']).first()
                    
                    if existing_product:
                        # 更新现有产品
                        for key, value in product_data.items():
                            setattr(existing_product, key, value)
                        existing_product.updated_at = datetime.now()
                        session.merge(existing_product)
                        print(f"更新产品: {product_data['asin']}")
                    else:
                        # 创建新产品
                        snake_case_product_data = convert_keys_to_snake_case(product_data)
                        new_product = AmazonProduct(**snake_case_product_data)
                        session.add(new_product)
                        print(f"创建新产品: {product_data['asin']}")
                    
                except Exception as e:
                    print(f"处理产品 {product_data.get('asin', 'unknown')} 时出错: {e}")
                    continue
            
            # 提交事务
            session.commit()
            print("所有产品数据已保存到数据库")
            
        except Exception as e:
            session.rollback()
            print(f"保存产品数据到数据库时出错: {e}")
            raise
        
        finally:
            session.close()
    # ===== 产品操作便捷方法 =====
    def parse_report_data(self, report_content: str) -> List[Dict]:
        """解析报告数据为产品列表"""
        from sqlalchemy import text

        products = []
        lines = report_content.strip().split('\n')
        if len(lines) < 2:  # 至少需要标题行和一行数据
            return products
            
        # 获取标题行
        headers = lines[0].split('\t')
        
        # 解析数据行
        for line in lines[1:]:
            values = line.split('\t')
            if len(values) != len(headers):
                continue
                
            product = dict(zip(headers, values))
            products.append(product)
            
        return products

    def process_products (self, products: List[Dict] ):
        """分批处理产品数据"""
        def convert_keys_to_snake_case(data):
            """将字典中的连字符键转换为下划线形式"""
            snake_case_data = {}
            for key, value in data.items():
                # 将连字符替换为下划线
                snake_key = key.replace('-', '_')
                snake_case_data[snake_key] = value
            return snake_case_data

# 使用转换后的字典创建对象

        total_products = len(products)
        session = self.session

        for product_data in   products:
            
            try:
                # 处理这一批产品
                
                        # 检查产品是否已存在（使用asin作为唯一标识）

                existing_product = session.query(AmazonProduct).filter_by(asin1=product_data['asin1'].strip()).first()

                # 获取数据库连接并执行SQL
                with session.connection() as conn:
                    result = conn.execute(
                        text("SELECT * FROM app_product_amz WHERE TRIM(asin1) = :asin"),
                        {"asin": product_data['asin1']}  # 参数化查询，避免SQL注入
                    )
                    existing_product = result.fetchone()  # 获取第一条记录

 
                if existing_product:
                    # 更新现有产品
                    for key, value in product_data.items():
                        setattr(existing_product, key, value)
                    existing_product.updated_at = datetime.now()
                    # 使用merge确保更新被保存
                    # session.merge(existing_product)
                    print(f"更新产品: {product_data['asin1']}")
                else:
                    # 创建新产品
                    snake_case_product_data = convert_keys_to_snake_case(product_data)
                    new_product = AmazonProduct(**snake_case_product_data)
                    new_product.open_date =datetime.strptime(new_product.open_date[:19], "%Y-%m-%d %H:%M:%S")
                    session.add(new_product)
                    print(f"创建新产品: {product_data['asin1']}")
                
                # 立即提交每个产品的更改
                session.commit()
                # 刷新会话以确保更改被保存
                session.flush()
                        
            except Exception as e:
                session.rollback()
                traceback.print_exc()
                print(f"处理产品 {product_data.get('asin', 'unknown')} 时出错: {e}")
                continue
                
                
            
           

    def download_products(self, marketplace_ids: List[str] = ["ATVPDKIKX0DER"]) -> None:
        """下载产品数据并分批处理"""
        # 创建报告请求
        report_type = "GET_MERCHANT_LISTINGS_ALL_DATA"
        # report_type = "GET_MERCHANT_LISTINGS_DATA"
        report_request = self.create_product_report(report_type, marketplace_ids)
        report_id = report_request["reportId"]
        print(f"已创建报告请求，ID: {report_id}")
        
        # 获取报告数据
        report_data = self.get_report_data(report_id)
        
        # 解析报告数据
        products = self.parse_report_data(report_data)
        print(f"成功解析 {len(products)} 个产品")
        
        # 分批处理产品
        self.process_products(products)
    
    def upload_products(self, feed_content: str, feed_type: str, marketplace_ids: List[str] = ["ATVPDKIKX0DER"]) -> Dict:
        """上传产品数据（支持新增、修改、删除）"""
        # 创建Feed文档
        document_info = self.create_feed_document()
        upload_url = document_info["uploadDestinationUri"]
        document_id = document_info["feedDocumentId"]
        
        # 上传Feed内容
        self.upload_feed_data(upload_url, feed_content)
        
        # 提交Feed处理请求
        feed_submission = self.submit_feed(feed_type, document_id, marketplace_ids)
        feed_id = feed_submission["feedId"]
        print(f"已提交Feed，ID: {feed_id}")
        
        return feed_submission
    
    def add_products(self, products_data: List[Dict], marketplace_ids: List[str] = ["ATVPDKIKX0DER"]) -> Dict:
        """新增产品（使用POST_PRODUCT_DATA Feed类型）"""
        # 转换为TSV格式
        tsv_data = self._convert_products_to_tsv(products_data)
        return self.upload_products(tsv_data, "POST_PRODUCT_DATA", marketplace_ids)
    
    def update_products(self, products_data: List[Dict], marketplace_ids: List[str] = ["ATVPDKIKX0DER"]) -> Dict:
        """更新产品（使用POST_PRODUCT_OVERRIDES_DATA Feed类型）"""
        tsv_data = self._convert_products_to_tsv(products_data)
        return self.upload_products(tsv_data, "POST_PRODUCT_OVERRIDES_DATA", marketplace_ids)
    
    def delete_products(self, skus: List[str], marketplace_ids: List[str] = ["ATVPDKIKX0DER"]) -> Dict:
        """删除产品（使用POST_PRODUCT_DATA Feed类型并设置Delete为Y）"""
        products_data = [{"SKU": sku, "Delete": "Y"} for sku in skus]
        tsv_data = self._convert_products_to_tsv(products_data)
        return self.upload_products(tsv_data, "POST_PRODUCT_DATA", marketplace_ids)
    
    def _convert_products_to_tsv(self, products_data: List[Dict]) -> str:
        """将产品数据转换为TSV格式"""
        if not products_data:
            return ""
        
        # 获取所有可能的字段名
        all_fields = set()
        for product in products_data:
            all_fields.update(product.keys())
        
        # 确保必需字段存在
        required_fields = ["SKU", "ProductName", "Brand", "Description", "Price", "Quantity"]
        for field in required_fields:
            if field not in all_fields:
                all_fields.add(field)
        
        # 排序字段
        sorted_fields = sorted(all_fields)
        
        # 生成TSV头部
        tsv_lines = ["\t".join(sorted_fields)]
        
        # 生成TSV行
        for product in products_data:
            row = []
            for field in sorted_fields:
                row.append(str(product.get(field, "")))
            tsv_lines.append("\t".join(row))
        
        return "\n".join(tsv_lines)
        
    def get_catalog_item(self,asin, marketplace_id="ATVPDKIKX0DER",includedData=['attributes']):  # 默认美国站
 
        try:
            access_token =self.access_token
            # self.endpoint = f"https://sellingpartnerapi-{self.region}.amazon.com/catalog/2020-12-01/items/{asin}"
            self.endpoint = f"https://sellingpartnerapi-na.amazon.com"
            url = f"{self.endpoint}/catalog/2020-12-01/items/{asin}"
            
            headers = {
                "Authorization": f"Bearer {access_token}",
                "x-amz-access-token": access_token,
                "x-amz-seller-id": self.SELLER_ID
            }
            params = {
                "marketplaceIds": [marketplace_id],
                "includedData": ["images", "salesRankings", "productTypes", "attributes", "summaries"]  # 增加五点描述
            }
            params = {
                "marketplaceIds": [marketplace_id],
                "includedData": ["salesRanks","attributes", "summaries"]  # 增加五点描述
            }
            params = {
                "marketplaceIds": [marketplace_id],
                "includedData": includedData   # 增加五点描述
            }
            
            response = requests.get(url, headers=headers, params=params)
            response.raise_for_status()
            return response.json()
        except Exception as e:
            print(f"获取产品数据失败: {e}")
            traceback.print_exc()
            msg=traceback.format_exc()
            time.sleep(10*60*random.random())
            return msg

    # 3. 搜索商品（通过关键词或 ASIN 列表）
    def search_catalog_items(self,query=None, asins=None, marketplace_id="ATVPDKIKX0DER"):
        self.refresh_access_token()
        access_token = self.access_token
        url = f"{self.endpoint}/catalog/2020-12-01/items/search"
        headers = {
            "Authorization": f"Bearer {access_token}",
            "x-amz-access-token": access_token,
            "x-amz-seller-id": self.SELLER_ID,
            "Content-Type": "application/json"
        }
        payload = {
            "marketplaceIds": [marketplace_id],
            "includedData": ["images", "salesRankings"]
        }
        if query:
            payload["query"] = query  # 关键词搜索
        if asins:
            payload["asin"] = asins  # ASIN 列表搜索（最多 50 个）
        
        response = requests.post(url, headers=headers, json=payload)
        response.raise_for_status()
        return response.json()
    
def sync_messages():
    global is_downingmessage
    current_directory = os.getcwd()
    config_file_path = os.path.join(current_directory, 'app','intereface_amazon','config.json')
    timespeed=45
    # 读取 JSON 文件
    with open(config_file_path, 'r', encoding='utf-8') as file:
        config_data = file.read()  # 读取文件内容为字符串

    # 解析 JSON 字符串
    config = json.loads(config_data) 
    credentials = {
        "lwa_client_id": config.get('client_id'),
        "lwa_client_secret": config.get('client_secret'),
        "refresh_token": config.get('refresh_token'),
    }
    api=None
    with downmessage_lock:
        if is_downingmessage:
            print("下载已经在进行中，请稍后再试。")
            return
        is_downloading = True  # 设置为正在下载
    # 初始化API客户端
        api = SPAPI(credentials, region="NA")  # 区域可选：NA, EU, JP
        
 
    headers = {
        'Authorization': f'Bearer {api.access_token}',
        'Content-Type': 'application/json',
        'x-amz-access-token': api.access_token
    }

    # 获取所有消息
    SP_API_URL = "https://sellingpartnerapi-na.amazon.com"  # 根据区域调整

    response = requests.get(f"{SP_API_URL}/messaging/v1/orders", headers=headers)
    messages = response.json().get('messages', [])

    for message in messages:
        message_id = message['messageId']
        content = message['content']
        sender = message['sender']
        thread_id = message['threadId']
        
        # 检查是否已同步
        if not api.session.query(Message2).filter(Message2.message_id == message_id).first():
    # 创建新的消息记录
            new_message = Message2.objects.create(
            message_id=message_id,
            content=content,
            sender=sender,
            thread=Message2.objects.get(thread_id=thread_id)  # 假设您有相应的线程
            )
            api.session.add(new_message)
            api.session.commit()
        else:
            existing_message = Message2.objects.get(message_id=message_id)
            if message['status'] != existing_message.is_read:
                existing_message.is_read = message['status']
                existing_message.save()
                api.session.commit()

def fetch_amazon_data_interface(public_class, admin_instance, request):
    # 使用示例
    global is_downloading
    current_directory = os.path.dirname(os.path.abspath(__file__))
    config_file_path = os.path.join(current_directory, 'apiconfig.json')
    timespeed=45
    # 读取 JSON 文件
    with open(config_file_path, 'r') as file:
        config = json.load(file)
        timespeed=config.get('timespeed', 45)
    credentials = {
        "lwa_client_id": "amzn1.application-oa2-client.948e72cc2a2d45e9a54e3ca191284bfb",
        "lwa_client_secret": "amzn1.oa2-cs.v1.dd8279b7214a5d7a98b834b585f6ac1d892d2e8bbcf33d7b235757af41c1249c",
        "refresh_token": "Atzr|IwEBINWJhPgyeG9bfXsHeduz71-c6ykUzBXov-urbj8o5wIJYz3iIogkYLnTSbV-Rndn_bkV0AtORZcvsqKQFR-c-6KRBZSj9A35siEzLJ_gH0euDb8U_rcZepee9FcjOFU4AMXz1JlVgJEYNHpu5j16e3d0D1cIZIeEw1i9UUGxXlRnE9TMFsmCypzgoYoEOKN7HUDiyOn_ODfR-iQzaDWVGfD2kIAPZCrhmgZ4zWeq3uB3b9jX1Yhokt9EBVp9L_hJkxNUZYjh2VRxdMwMuSb-d8Vjd-6lywbdGjdjzC9zR0gIiD2k7qZtdmyXIhVonq7Mu3Ulhi6yUMp_1GtNnpkn-Zur",
    }
    with download_lock:
        if is_downloading:
            print("下载已经在进行中，请稍后再试。")
            return
        is_downloading = True  # 设置为正在下载
    # 初始化API客户端
        api = SPAPI(credentials, region="NA")  # 区域可选：NA, EU, JP
        
        try:
            is_downloading = True
            print("正在下载产品数据...")
            # api.download_products()
            # 读取所有amazon_product表中的asin,然后逐个读取所有对象，然后调用get_catalog_item方法，将结果保存到数据库中
            # products = api.session.query(AmazonProduct).all()


            # 查询同时满足 bullet_point1 和 bullet_point2 为 NULL 的产品
            if public_class==Amazon_asinupload_xue_todb:
                products = api.session.query(public_class).filter(
                    or_(
                        and_(
                            public_class.detail1 == null(),
                            public_class.detail2 == null()
                        ),
                        or_(
                            public_class.category1 == null(),
                            public_class.category2 == null()
                        )
                    ),
                    func.coalesce(public_class.trytimes, 0) < 3
                ).order_by(desc(public_class.opdate)).limit(100).all()
            else:
                products = api.session.query(public_class).filter(
                    public_class.bullet_point1 == null(),
                    public_class.bullet_point2 == null(),
                    func.coalesce(public_class.trytimes, 0) < 3
                ).limit(100).all()
            # for product in products:
            #     print(f"ASIN: {product.asin1} ")  #
    
            # products = api.session.execute(text("SELECT * FROM app_product_amz where    bullet_point1 is null and bullet_point2 is null   ")).all()
            # products=[]
            for product in products:
                current_directory = os.path.dirname(os.path.abspath(__file__))
                config_file_path = os.path.join(current_directory, 'apiconfig.json')
                timespeed=45
                # 读取 JSON 文件
                if product.trytimes is None:
                    product.trytimes=0
                product.trytimes+=1
                with open(config_file_path, 'r') as file:
                    config = json.load(file)
                    timespeed=config.get('timespeed', 45)
                asin=''
                if public_class==Amazon_asinupload_xue_todb: 
                    asin=product.asin
                    product.opdate=datetime.now()
                else:
                    asin=product.asin1
                result=api.get_catalog_item(asin,includedData=['attributes'])
                # print(result)
                # 把result写入数据库
                
                if 'MaxRetryError' in result:
                    time.sleep(10*60*random.random())
                    continue
                if result and "attributes" in result and result.get("attributes"):

                    attributes=result.get("attributes")
                    print(datetime.now(),asin,'开始下载属性',attributes)
                    if admin_instance:
                        admin_instance.message_user(request, f"获取产品数据: {result}" )

                    if attributes.get("bullet_point"):
                        if public_class==Amazon_asinupload_xue_todb:
                            blen=min(5,len(attributes.get("bullet_point")))
                            for i in range(blen):
                                setattr(product, f'detail{i+1}',  attributes.get("bullet_point")[i]["value"]) 
                        else:
                            blen=len(attributes.get("bullet_point"))
                            for i in range(blen):
                                print(attributes.get("bullet_point")[i]["value"]) 
                            setattr(product, f'bullet_point{i+1}',  attributes.get("bullet_point")[i]["value"]) 
                        if attributes.get("brand"):    
                            product.brand=  attributes.get("brand")[0]["value"] 
                        if attributes.get("item_package_weight"):    
                            product.item_package_weight=json.dumps(attributes.get("item_package_weight"))
                            product.item_package_weight=json.dumps(attributes.get("item_package_weight"))
                        if attributes.get("item_package_dimensions"):    
                            product.item_package_dimensions=json.dumps(attributes.get("item_package_dimensions"))
                        
                        if attributes.get("item_type_keywords"):    
                            product.item_type_keywords=json.dumps(  attributes.get("item_type_keywords"))
                        
                        if attributes.get("material"):    
                            product.item_type_keywords=json.dumps(attributes.get("material"))
                            
                        if attributes.get("color"):    
                            product.item_type_keywords=json.dumps(attributes.get("color"))
                        else:
                            print(datetime.now(),asin,'没有属性')
                            product.opdate=datetime.now()
                            if public_class==Amazon_asinupload_xue_todb: 
                                product.detail1='no attribute'
                                product.detail2='no attribute'
                            else:
                                product.bullet_point1='no attribute'
                                product.bullet_point2='no attribute'
                            api.session.commit()
                            continue

                api.session.commit()
                time.sleep(timespeed*random.random()) # if product.image2==none
                if product.image2==None:
                    print(datetime.now(),asin,'开始下载图片')

                    result=api.get_catalog_item(asin,includedData=['images'])
                    if admin_instance:
                        admin_instance.message_user(request, f"获取产品数据: {result}" )
                    try:
                        image_list =result['images'][0]['images']
                        sorted_images = sorted(image_list, key=lambda x: x['height'] + x['width'], reverse=True)
                        blen=min( len(sorted_images),10)
                        product.image_url=sorted_images[0]['link']
                        
                        for i in range(blen):
                            image_url=sorted_images[i]['link']
                            setattr(product, f'image{i+2}',  image_url) 
                    except Exception as e:
                        traceback.print_exc()
                    finally:
                        time.sleep(timespeed*random.random())
                api.session.commit()
                result=api.get_catalog_item(asin,includedData=['salesRanks'])
                # result=api.get_catalog_item('B0CHJQFM7B',includedData=['salesRanks'])
                try:
                    
                    if admin_instance:
                        admin_instance.message_user(request, f"获取产品数据: {result}" )
                    product.updated_at=datetime.now()
                    salesRanks=result['salesRanks'][0]['ranks']
                    
                    sorted_ranks = sorted(salesRanks, key=lambda x: x['rank'], reverse=True)
                    blen=min(3,len(sorted_ranks))
                    
                    for i in range(len(salesRanks)):
                        # print(salesRanks[i]['title'],salesRanks[i]['rank'])
                        setattr(product, f'category{i+1}',  salesRanks[i]['title']) 
                        setattr(product, f'rank{i+1}',  salesRanks[i]['rank']) 
                    api.session.commit()
                    print(datetime.now(),asin,'排名',salesRanks)
                except Exception as e:
                    traceback.print_exc()
                finally:
                    time.sleep(timespeed*random.random())
        except Exception as e:
            print(f"下载失败: {e}")
            traceback.print_exc()
        finally:
            is_downloading = False  #
 
if __name__ == "__main__":
    # 替换为你的真实凭证    
    # fetch_amazon_data_interface(Amazon_asinupload_xue_todb,None,None)
    sync_messages()